﻿using System;
using System.Text;

namespace BtcsCon
{
    public class BtcsClient
    {
        private string pub_topic_;
        private string sub_topic_;
        private string broker_ip_;
        private string pub_id_;
        private string sub_id_;
        private string username_;
        private string passwd_;
        private MqttClient mqtt_;

        public BtcsClient()
        {
            pub_topic_ = "btcs/sub";
            sub_topic_ = "btcs/pub";
            broker_ip_ = "192.168.30.156";
            //broker_ip_ = "127.0.0.1";
            pub_id_ = "btcs-publisher1";
            sub_id_ = "btcs-subscriber1";
            username_ = "admin";
            passwd_ = "public";

            try
            {
                mqtt_ = new MqttClient(btcsHandler, pub_topic_, sub_topic_, broker_ip_, pub_id_, sub_id_, username_, passwd_);
            }
            catch (Exception e)
            {
                throw new Exception("BtcsClient Error: " + e.ToString());
            }
        }

        public bool sendHeartbeat()
        {
            //Build
            string commandType = BTCSAck.TYPECODE;
            string commandCode = "2001";
            string deviceSn = "AGV";

            string cc_deviceSn = "12345789";
            string cc_deviceTypeSn = "AGV";
            string cc_ip = "192.168.1.110";
            string cc_token = "token_1234567";
            string cc_status = "Y";
            string cc_activeStatus = "Y";
            string cc_deviceStyle = "device";
            string cc_productid = "productid_";
            string cc_currentStatus = "0";

            string cs_currentVelocity = "0";
            string cs_maxVelocity = "1";
            string cs_maxReverseVelocity = "30";
            string cs_loadRange = "1.5T";
            string cs_driveType = "driveType_2wheel";
            string cs_navigationType = "1";
            string cs_nodeSn = "003000";
            string cs_nextNodeSn = "004000";
            string cs_xPosition = "5";
            string cs_yPosition = "6";
            string cs_power = "77";
            string cs_mode = "1";
            string cs_headStockAngle = "180";
            string cs_taskStatus = "0";

            BTCSAck ack = new BTCSAck();
            ack.commandType = commandType;
            ack.commandCode = commandCode;
            ack.deviceSn = deviceSn;
            ack.commandcontent.deviceSn = cc_deviceSn;
            ack.commandcontent.deviceTypeSn = cc_deviceTypeSn;
            ack.commandcontent.ip = cc_ip;
            ack.commandcontent.token = cc_token;
            ack.commandcontent.status = cc_status;
            ack.commandcontent.activeStatus = cc_activeStatus;
            ack.commandcontent.deviceStyle = cc_deviceStyle;
            ack.commandcontent.productId = cc_productid;
            ack.commandcontent.currentStatus = cc_currentStatus;
            ack.commandcontent.deviceAttrInfo.currentVelocity = cs_currentVelocity;
            ack.commandcontent.deviceAttrInfo.maxVelocity = cs_maxVelocity;
            ack.commandcontent.deviceAttrInfo.maxReverseVelocity = cs_maxReverseVelocity;
            ack.commandcontent.deviceAttrInfo.loadRange = cs_loadRange;
            ack.commandcontent.deviceAttrInfo.driveType = cs_driveType;
            ack.commandcontent.deviceAttrInfo.navigationType = cs_navigationType;
            ack.commandcontent.deviceAttrInfo.nodeSn = cs_nodeSn;
            ack.commandcontent.deviceAttrInfo.nextNodeSn = cs_nextNodeSn;
            ack.commandcontent.deviceAttrInfo.xPosition = cs_xPosition;
            ack.commandcontent.deviceAttrInfo.yPosition = cs_yPosition;
            ack.commandcontent.deviceAttrInfo.power = cs_power;
            ack.commandcontent.deviceAttrInfo.mode = cs_mode;
            ack.commandcontent.deviceAttrInfo.headStockAngle = cs_headStockAngle;
            ack.commandcontent.deviceAttrInfo.taskStatus = cs_taskStatus;

            // Serilized&Publish
            string json_str = Json.toJson(ack);
            return mqtt_.publish(json_str);
        }

        public bool sendRequest()
        {
            //TODO
            return false;
        }

        private void btcsHandler(byte[] data)
        {
            try
            {
                string json_str = Encoding.UTF8.GetString(data, 0, data.Length);
                System.Console.WriteLine("Recv(BtcsClient) > {0}", json_str);

                BTCSInfo cmd = Json.jsonTo(json_str);
                if (cmd == null)
                {
                    Console.WriteLine("btcsHandler Null Data.");
                    return;
                }

                switch (cmd.commandType)
                {
                    case BTCSTask.TYPECODE:
                        BTCSTask task = (BTCSTask)cmd;
                        task_handler(task);
                        break;
                    case BTCSDevice.TYPECODE:
                        BTCSDevice device = (BTCSDevice)cmd;
                        device_handler(device);
                        break;
                    case BTCSAction.TYPECODE:
                        BTCSAction action = (BTCSAction)cmd;
                        action_handler(action);
                        break;
                    default:; break;
                }
            }
            catch (Exception e)
            {
                Console.WriteLine("Btcs Error: " + e.ToString());
            }
        }

        private void task_handler(BTCSTask task)
        { // 下发任务处理句柄
            Console.WriteLine("{0} {1} {2}", task.commandType, task.commandCode, task.deviceSn);
            Console.WriteLine("{0} {1} {2}", task.commandcontent.taskType, task.commandcontent.startSn, task.commandcontent.endSn);
            Console.WriteLine("{0} {1}", task.commandcontent.pathDtos[0].roadType, task.commandcontent.pathDtos[0].startPointDto.pointSn);

            Console.WriteLine("task_handler > {0}", Json.toJson(task));
        }

        private void device_handler(BTCSDevice device)
        { // 下发设备信息处理句柄
            Console.WriteLine("{0} {1} {2}", device.commandType, device.commandCode, device.deviceSn);

            Console.WriteLine("device_handler > {0}", Json.toJson(device));
        }

        private void action_handler(BTCSAction action)
        { // 下发动作处理句柄
            Console.WriteLine("{0} {1} {2}", action.commandType, action.commandCode, action.deviceSn);

            Console.WriteLine("action_handler > {0}", Json.toJson(action));
        }
    }
}
